package com.onefish.toolkit;

import cn.hutool.core.date.DateUtil;

import java.io.RandomAccessFile;
import java.lang.management.ManagementFactory;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.charset.StandardCharsets;

public class NioHelper2 {
    public static void main(String[] args) throws Exception {
        String processId = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
        System.out.println(DateUtil.now() + " NioHelper2 当前进程id -> " + processId);
        String path = "C:\\Users\\Administrator\\Desktop\\1.txt";
        RandomAccessFile randomAccessFile = new RandomAccessFile(path,"rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        System.out.println(DateUtil.now() + " NioHelper2 开始加锁操作 ... ");
        //  区分独占锁[排它锁]和共享锁
//        fileChannel.lock();
//                fileChannel.lock(0, fileChannel.size(),true);
//        FileLock fileLock = fileChannel.tryLock();
        FileLock fileLock = fileChannel.tryLock(0,3,true);
        if (fileLock == null){
            System.out.println(DateUtil.now() + " NioHelper2 tryLock null");
        }
        System.out.println(DateUtil.now() + " NioHelper2 加锁完成！");
        //  验证共享锁在多进程之间读是否允许 -> Yes
//        long position = 0;
//        int size = 3;
//        ByteBuffer buffer = ByteBuffer.allocate(size);
//        fileChannel.read(buffer,position);
//        //切换模式并将文件指针移到文件首
//        buffer.flip();
//        byte [] bytes = new byte[size];
//        buffer.get(bytes);
//        String str = new String(bytes);
//        System.out.println(str);

        //  验证共享锁在多进程之间写是否允许 -> No
        //  Exception: 另一个程序已锁定文件的一部分，进程无法访问。
        String content = "aaa";
        byte [] writeBytes = content.getBytes(StandardCharsets.UTF_8);
        ByteBuffer writeByteBuffer = ByteBuffer.wrap(writeBytes);
        fileChannel.write(writeByteBuffer,3);
        System.out.println(DateUtil.now() + " NioHelper2 字符串写入成功！");

        Thread.sleep(Integer.MAX_VALUE);
        randomAccessFile.close();
        fileChannel.close();
    }
}
